package org.grow.infru.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.QueryResults;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.grow.common.dto.PagedResults;
import org.grow.infru.dao.MaterialRepository;
import org.grow.infru.dao.TestBillRepository;
import org.grow.infru.entity.*;
import org.grow.infru.entity.QTestBill;
import org.grow.infru.service.CodeGene;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

/**
 * @Author: xwg
 * @CreateDate: 2022/1/20
 */
@RequestMapping("/testBill")
@RestController
public class TestBillController {
    @Autowired
    private ThreadLocal<CodeGene> codeGeneThreadLocal;
    @Autowired
    private TestBillRepository testBillRepository;

    @PostMapping("/insert")
    public TestBill insert(@RequestBody TestBill testBill) {
        testBill.setBillCode(codeGeneThreadLocal.get().nextCode("TEST"));
//        初次进行业务初始化 来自前端不信任的数据
        testBill.setVersion(0);
        TestBill save = testBillRepository.save(testBill);
        return save;
    }

    @GetMapping("/find/{code}")
    public Optional<TestBill> findByPk(@PathVariable("code") String code) {
        Optional<TestBill> id = testBillRepository.findById(code);
//        System.out.println("=======test===eager");
//        fetch type lazy时候 查询语句不是连表 而responsebody注解序列化时候会补充
        return id;
    }

    @PostMapping("/modify")
    public TestBill modify(@RequestBody TestBill testBill) {
//        修改一个领域实体 = one的修改和many的增删改
//        需要提前做出哪些校验呢？ testBillId是否存在
//        级联修改 如果是新增的子项但是id是已有的id 就会覆盖已有的外键，导致外键update
//        导致发生 主表之间抢夺子项的不合法  应该报错比较合适 或者 修改只能修改单项 不允许级联
        TestBill save = testBillRepository.save(testBill);
        return save;

    }

    @DeleteMapping("/delete/{code}")
    public Boolean delete(@PathVariable("code") String code) {
        try {
            testBillRepository.deleteById(code);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    @Autowired
    private MaterialRepository materialRepository;

    @GetMapping("/queryMaterial")
    public List<MaterialCargo> queryMaterial() {
        return materialRepository.findAll();
    }

    @GetMapping("/material/{code}")
    public Optional<MaterialCargo> findMaterial(@PathVariable("code") String code) {
        Optional<MaterialCargo> r = materialRepository.findById(code);
        return r;
    }
    QTestBill tb = QTestBill.testBill;
    @Autowired
    private JPAQueryFactory jpaQueryFactory;
    @Autowired
    private ObjectMapper objectMapper;
    @PostMapping("/query")
    public PagedResults<TestBill> query(@RequestBody TestBillQueryCondition qc){
        Integer pageNum = qc.getPageNum();
        Integer pageSize = qc.getPageSize();
        Integer pageStart = (pageNum-1)*pageSize;
        BooleanBuilder builder = new BooleanBuilder();
        /**
         *     private String billCodeSml;
         *     private LocalDateTime billMadeTimeMin;
         *     private LocalDateTime billMadeTimeMax;
        * */
        if (StringUtils.hasText(qc.getBillCodeSml())) {
            builder.and(tb.billCode.like("%"+qc.getBillCodeSml()+"%"));
        }

        if (qc.getBillMadeTimeMin()!=null) {
            builder.and(tb.billMadeTime.after(qc.getBillMadeTimeMin()));
        }
        if (qc.getBillMadeTimeMax()!=null) {
            builder.and(tb.billMadeTime.before(qc.getBillMadeTimeMax()));
        }

        QueryResults<TestBill> r = jpaQueryFactory.selectFrom(tb)
                .where(builder)
                .orderBy(tb.billMadeTime.desc())
                .offset(pageStart)
                .limit(pageSize)
                .fetchResults();

        try {
            System.out.println(objectMapper.writeValueAsString(r.getResults()));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        return new PagedResults<TestBill>(r.getTotal(),r.getResults());

    }


}
